﻿using Link_eLab.WeChatTools.Dao;
using Link_eLab.WeChatTools.Model;
using Newtonsoft.Json.Linq;
using Senparc.Weixin.MP.AdvancedAPIs;
using System;
using System.IO;
using System.Net;
using System.Text;

namespace Link_eLab.WeChatTools.Service.Impl
{
    public class WeChatToolsService : IWeChatToolsService
    {
        private readonly IWeChatDao WeChatDao;

        #region 构造函数

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="weChatDao"></param>
        public WeChatToolsService(IWeChatDao weChatDao)
        {
            WeChatDao = weChatDao;
        }

        #endregion

        #region 发送推送请求到微信服务器，检查是否发送成功

        /// <summary>
        /// 发送推送请求到微信服务器，检查是否发送成功
        /// </summary>
        /// <param name="weChatOpenId"></param>
        /// <param name="templateId"></param>
        /// <param name="templateData"></param>
        /// <returns>JSON结果集</returns>
        public bool SendRequestToWechatServer(string weChatOpenId, string templateId, dynamic templateData)
        {
            Console.WriteLine($"\n接收到的微信推送请求接口返回的信息");
            Console.WriteLine($"weChatOpenId：{weChatOpenId}");
            Console.WriteLine($"templateId：{templateId}");
            Console.WriteLine($"templateData：{templateData}");

            bool pushSuccess = false;
            string accessToken = WeChatDao.RedisGet("wx_access_token").Access_Token;

            try
            {
                #region 获取存储在Redis服务器的微信access_token

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine("\n已读取到存储在 Redis 服务器的 Access_Token");
                    accessToken = WeChatDao.RedisGet("wx_access_token").Access_Token;
                }
                else
                {
                    Console.WriteLine("\n未读取到存储在 Redis 服务器的 Access_Token，调用微信接口重新获取");

                    #region 调用微信接口获取临时 access_token

                    // 微信登录凭证校验接口
                    string Url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={WeChatConsts.appId}&secret={WeChatConsts.secret}";

                    // 生成的Url
                    Console.WriteLine($"\nUrl：{Url}");

                    // 存储接口返回的数据
                    string result = null;

                    // Web请求
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                    request.Method = "GET";
                    request.Accept = "application/json";
                    request.ContentType = "application/json; charset=utf-8";
                    request.ContentLength = 0;

                    // 获取接口返回值
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                    // 以流的方式读取返回的数据
                    Stream stream = response.GetResponseStream();

                    // 获取内容
                    using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        result = reader.ReadToEnd();
                    }

                    // 打印返回的参数
                    Console.WriteLine("\n微信接口返回的内容：" + result);

                    // 字符串转 json 方式
                    JObject jo = JObject.Parse(result);
                    Console.WriteLine("\n转换返回的数据为 JSON 对象：" + jo);
                    Console.WriteLine("JSON 对象内的 errcode 字段值：" + jo["errcode"]);
                    Console.WriteLine("JSON 对象内的 errmsg 字段值：" + jo["errmsg"]);
                    Console.WriteLine("JSON 对象内的 access_token 字段值：" + jo["access_token"]);
                    Console.WriteLine("JSON 对象内的 expires_in 字段值：" + jo["expires_in"]);

                    if (jo["access_token"] != null)
                    {
                        accessToken = jo["access_token"].ToString();

                        // 将生成的数据存储到Redis数据库中，有效时间为7200秒 (微信官方设定的有效时间)
                        WeChatDao.RedisSet("wx_access_token", new WeChatModel() { Access_Token = accessToken }, 7200);
                    }

                    #endregion

                }

                #endregion

                #region 如果 access_token 不等于空时执行模板消息推送操作

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine("\n微信接口返回数据验证已通过，执行模板消息推送操作。");
                    var pushResult = TemplateApi.SendTemplateMessage(accessToken, weChatOpenId, templateId, WeChatConsts.eLabDomain, templateData, null);
                    pushSuccess = pushResult.errcode.ToString() == WeChatConsts.weChatRequestSuccessCode;
                    Console.WriteLine($"\npushResult：{pushResult}");
                }
                else
                {
                    Console.WriteLine("\n未读取到微信接口返回的 access_token 字段，停止推送操作并返回错误信息。");
                }

                #endregion

            }
            catch (Exception e)
            {
                Console.WriteLine($"\nMessage：{e}");
            }

            return pushSuccess;
        }

        #endregion
    }
}
